package com.cancer.common.web;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import com.cancer.common.util.StringUtil;

/**
 * 排序
 * 
 * @company GeekPlus
 * @project beetle
 * @author 刘俊
 * @date 2016年4月16日
 * @since 1.0.0
 */
public class Sort {
	public static final Direction DEFAULT_DIRECTION = Direction.ASC;

	private List<Order> orders = new ArrayList<Order>();

	public Sort() {
	}

	public Sort(Order... order) {

		this.add(order);
	}

	public Sort(Direction direction, String property) {

		this.add(direction, property);
	}

	public Sort add(Order... order) {
		for (Order o : order) {
			orders.add(o);
		}

		return this;
	}

	public Sort add(Direction direction, String property) {
		orders.add(new Order(direction, property));

		return this;
	}

	public List<Order> getOrders() {
		return orders;
	}

	public void setOrders(List<Order> orders) {
		this.orders = orders;
	}

	public static class Order implements Serializable {
		private static final long serialVersionUID = 1522511010900108987L;

		private final Direction direction;
		private final String property;

		public Order(String property) {
			this(DEFAULT_DIRECTION, property);
		}

		public Order(Direction direction, String property) {
			if (StringUtil.isEmpty(property)) {
				throw new IllegalArgumentException("Property must not null or empty!");
			}

			this.direction = direction == null ? DEFAULT_DIRECTION : direction;
			this.property = property;
		}

		public Direction getDirection() {
			return direction;
		}

		public String getProperty() {
			return property;
		}

		public boolean isAscending() {
			return this.direction.equals(Direction.ASC);
		}

		@Override
		public String toString() {
			String result = String.format("%s: %s", property, direction);

			return result;
		}
	}

	public static enum Direction {
		ASC, DESC;

		public static Direction fromString(String value) {

			try {
				return Direction.valueOf(value.toUpperCase(Locale.US));
			} catch (Exception e) {
				throw new IllegalArgumentException(String.format(
						"Invalid value '%s' for orders given! Has to be either 'desc' or 'asc' (case insensitive).", value), e);
			}
		}

		public static Direction fromStringOrNull(String value) {

			try {
				return fromString(value);
			} catch (IllegalArgumentException e) {
				return null;
			}
		}
	}
}
